﻿Imports System.Runtime.CompilerServices
Imports System.Text
Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary
Friend Class myComparer
    Implements IEqualityComparer(Of Int32())


    Public Function Equals2(x() As Integer, y() As Integer) As Boolean Implements IEqualityComparer(Of Integer()).Equals
        Try
            Dim a As Int32 = x.Length - 1
            For b = 0 To a
                If Not x(b) = y(b) Then
                    Return False
                End If
            Next
            Return True
        Catch ex As Exception
            Throw
        End Try
    End Function

    Public Function GetHashCode2(obj() As Integer) As Integer Implements IEqualityComparer(Of Integer()).GetHashCode
        Return 0
    End Function
End Class
Public Module myconst

    Public colors As Dictionary(Of Int32, String)
    Public randomType As Int32 = 1
    Public justifyLeftType = 2
    Public justifyEx As Boolean = True
    Public document As Boolean = False
    Public check As Boolean = False
    Public r As Single = 0
    Public pop3 As Boolean
    Public reg2 As Boolean
    Public rbrs_obj_min As Boolean = True

    Public RandNum As System.Random
    Public randConst As Boolean = True
    Public randConstV As Int32 = 0
    Public reuse As Boolean = False
    Public randInit As Boolean = True
    Public usePeaks As Boolean = True
    Public divider As Single = 1
    Public selectBadOnes As Boolean = False
    Public planDirect As Boolean = False
    Public IsHGA11 As Boolean = False

    Public peakLimitConst As Int32 = 10
    Public peaklimitDyn As Boolean = False
    Public peakDebels As Boolean = False
    Public peakFangWang As Boolean = False
    Public peakFangWangType As Int32 = 1
    Public diversityControl As Boolean = False
    Public detectClones As Boolean = False
    Public countClones As Boolean = True
    '  Public tres As Single
    Private bAllLimited As Boolean = False
    Public Const COL_TASK As String = "task"
    Public Const COL_KEY As String = "key"
    Public Const COL_DUR As String = "dur"
    Public Const COL_PRE As String = "pre"
    Public Const COL_POST As String = "post"
    Private Sub consoleout(ByVal ret, ByVal count, ByVal typ)
        Try
            '            Console.Write(Environment.NewLine)
            Console.SetCursorPosition(0, Console.CursorTop)
            Console.ForegroundColor = ConsoleColor.White
            Console.Write("J" & typ & "-" & count & " | " & Math.Round(ret(0), 3) & " | " & Math.Round(ret(1) / 100, 4) & " | " &
                                New TimeSpan(0, 0, 0, 0, Math.Round(ret(2), 0)).ToString & " | " & Math.Round(ret(3), 3) & " | " &
                                 ret(4).ToString.Substring(0, 8) & "_" & ret(4).ToString.Substring(8, 6))
            Console.ForegroundColor = ConsoleColor.Gray
            Console.Write(Environment.NewLine)
        Catch ex As Exception
            Throw
        End Try
    End Sub

    Sub Config_Valls_Default()
        pop3 = False
        reg2 = False
        r = 0.05
        randomType = 2
        randInit = False
        randConst = False
        divider = 1
        rbrs_obj_min = True
        peakLimitConst = 0
        peaklimitDyn = False
        peakDebels = False
        peakFangWang = False
        usePeaks = True
        detectClones = True
        countClones = True
        IsHGA11 = False
        diversityControl = False
    End Sub
    Sub TestSet_30_1000()
        Try
            Dim bTest As Boolean = False
            Dim tl As New clsTaskLib
            'For i = 1 To 2
            Console.WriteLine("--------- J30 1000 test 10 times  -------")
            For i = 1 To 10
                Dim nSch() As Int32 = New Int32() {1000}
                For Each n As Int32 In nSch
                    consoleout(tl.CalcJ30All(n, bTest), n, "30")
                Next
            Next
        Catch ex As Exception
            Throw
        End Try
    End Sub
    Sub TestSet_30_50000()
        Try
            Dim bTest As Boolean = False
            Dim tl As New clsTaskLib
            'For i = 1 To 2
            Console.WriteLine("--------- J30 50.000 test 4 time (no Clones/Clones) -------")

            For i = 1 To 4
                Select Case i
                    Case 1
                        detectClones = True
                    Case 2
                        detectClones = True
                    Case 3
                        detectClones = False
                    Case 4
                        detectClones = False
                End Select
                Dim nSch() As Int32 = New Int32() {50000}
                For Each n As Int32 In nSch
                    consoleout(tl.CalcJ30All(n, bTest), n, "30")
                Next
            Next
        Catch ex As Exception
            Throw
        End Try
    End Sub
    Sub TestSet_allow_Clones()
        Try
            Dim bTest As Boolean = False
            Dim tl As New clsTaskLib
            'For i = 1 To 2
            Console.WriteLine("--------- Allow clones  -------")
            detectClones = False
            Dim nSch() As Int32 = New Int32() {1000, 5000}
            For Each n As Int32 In nSch
                consoleout(tl.CalcJ30All(n, bTest), n, "30")
                consoleout(tl.CalcJ60All(n, bTest), n, "60")
                consoleout(tl.CalcJ90All(n, bTest), n, "90")
                consoleout(tl.CalcJ120All(n, bTest), n, "120")
            Next
        Catch ex As Exception
            Throw
        End Try
    End Sub
    Sub TestSet_diversity()
        Try
            Dim bTest As Boolean = False
            Dim tl As New clsTaskLib
            'For i = 1 To 2
            Console.WriteLine("--------- Diversity  -------")
            diversityControl = True
            Dim nSch() As Int32 = New Int32() {1000, 5000}
            For Each n As Int32 In nSch
                consoleout(tl.CalcJ30All(n, bTest), n, "30")
                consoleout(tl.CalcJ60All(n, bTest), n, "60")
                consoleout(tl.CalcJ90All(n, bTest), n, "90")
                consoleout(tl.CalcJ120All(n, bTest), n, "120")
            Next
        Catch ex As Exception
            Throw
        End Try
    End Sub
    Sub TestSet_no_CloneCount()
        Try
            Dim bTest As Boolean = False
            Dim tl As New clsTaskLib
            'For i = 1 To 2
            Console.WriteLine("--------- No clones count  -------")
            detectClones = True
            countClones = False
            Dim nSch() As Int32 = New Int32() {1000, 5000}
            For Each n As Int32 In nSch
                consoleout(tl.CalcJ30All(n, bTest), n, "30")
                consoleout(tl.CalcJ60All(n, bTest), n, "60")
                consoleout(tl.CalcJ90All(n, bTest), n, "90")
                consoleout(tl.CalcJ120All(n, bTest), n, "120")
            Next
        Catch ex As Exception
            Throw
        End Try
    End Sub

    Sub TestSet_Peaks()
        Try
            Dim bTest As Boolean = False
            'For z = 1 To 10
            'tl.CalcJ30Single(5000)
            ' Next
            Dim tl As New clsTaskLib

            '  For i = 1 To 2
            For Each peakC In New Boolean() {True, False}
                Console.WriteLine("--------- PEAK MAX --- DYN --- " & peakC.ToString & " -------")
                peaklimitDyn = peakC
                If peakC Then
                    peakLimitConst = 0
                End If

                Dim nSch() As Int32 = New Int32() {1000, 5000}
                For Each n As Int32 In nSch
                    If Not peakC Then peakLimitConst = 2
                    consoleout(tl.CalcJ30All(n, bTest), n, "30")
                    If Not peakC Then peakLimitConst = 4
                    consoleout(tl.CalcJ60All(n, bTest), n, "60")
                    If Not peakC Then peakLimitConst = 6
                    consoleout(tl.CalcJ90All(n, bTest), n, "90")
                    If Not peakC Then peakLimitConst = 8
                    consoleout(tl.CalcJ120All(n, bTest), n, "120")
                Next
                'Next
            Next
            'consoleout(tl.CalcJ30All(1000), 1000, "30")

        Catch ex As Exception
            Throw
        End Try
    End Sub
    Sub TestSet_phase1_ext()
        Try
            Dim bTest As Boolean = False
            IsHGA11 = True
            usePeaks = False
            For Each x In New Single() {0, 0.05}
                r = x
                Dim tl As New clsTaskLib
                'For i = 1 To 2
                Console.WriteLine("--------- PHASE 1 ohne Crossover " & x & "  -------")
                Dim nSch() As Int32 = New Int32() {1000, 5000}
                For Each n As Int32 In nSch
                    consoleout(tl.CalcJ30All(n, bTest), n, "30")
                    consoleout(tl.CalcJ60All(n, bTest), n, "60")
                    consoleout(tl.CalcJ90All(n, bTest), n, "90")
                    consoleout(tl.CalcJ120All(n, bTest), n, "120")
                Next
                'Next
            Next
        Catch ex As Exception
            Throw
        End Try
    End Sub
    Sub TestSet_debels()
        Try
            Dim bTest As Boolean = False
            Dim tl As New clsTaskLib
            peakDebels = True
            '  For i = 1 To 2
            Console.WriteLine("--------- PEAK Debels -------")
            Dim nSch() As Int32 = New Int32() {1000, 5000}
            For Each n As Int32 In nSch
                consoleout(tl.CalcJ30All(n, bTest), n, "30")
                consoleout(tl.CalcJ60All(n, bTest), n, "60")
                consoleout(tl.CalcJ90All(n, bTest), n, "90")
                consoleout(tl.CalcJ120All(n, bTest), n, "120")
            Next
            'Next
        Catch ex As Exception
            Throw
        End Try
    End Sub
    Sub TestSet_fangWangv3()
        Try
            Dim bTest As Boolean = False
            Dim tl As New clsTaskLib
            peakFangWang = True
            peakDebels = False

            '  For i = 1 To 2
            For Each typ As Int32 In New Int32() {3}
                peakFangWangType = typ
                Console.WriteLine("--------- PEAK Fang/Wang v" & typ & "-------")
                Dim nSch() As Int32 = New Int32() {1000, 5000, 50000}
                If bAllLimited Then
                    nSch = New Int32() {1000, 5000}
                End If

                For Each n As Int32 In nSch
                    consoleout(tl.CalcJ30All(n, bTest), n, "30")
                    consoleout(tl.CalcJ60All(n, bTest), n, "60")
                    consoleout(tl.CalcJ90All(n, bTest), n, "90")
                    consoleout(tl.CalcJ120All(n, bTest), n, "120")
                Next
            Next
            'Next
        Catch ex As Exception
            Throw
        End Try
    End Sub
    Sub TestSet_fangWang()
        Try
            Dim bTest As Boolean = False
            Dim tl As New clsTaskLib
            peakFangWang = True
            peakDebels = False
            '  For i = 1 To 2
            For Each typ As Int32 In New Int32() {1, 2}
                peakFangWangType = typ
                Console.WriteLine("--------- PEAK Fang/Wang v" & typ & "-------")
                Dim nSch() As Int32 = New Int32() {1000, 5000}
                For Each n As Int32 In nSch
                    consoleout(tl.CalcJ30All(n, bTest), n, "30")
                    consoleout(tl.CalcJ60All(n, bTest), n, "60")
                    consoleout(tl.CalcJ90All(n, bTest), n, "90")
                    consoleout(tl.CalcJ120All(n, bTest), n, "120")
                Next
            Next
            'Next
        Catch ex As Exception
            Throw
        End Try
    End Sub
    Sub TestSet_phase1()
        Try
            Dim bTest As Boolean = False
            IsHGA11 = True
            Dim tl As New clsTaskLib
            '  For i = 1 To 2
            Console.WriteLine("--------- PHASE 1 -------")
            Dim nSch() As Int32 = New Int32() {1000, 5000}
            For Each n As Int32 In nSch
                consoleout(tl.CalcJ30All(n, bTest), n, "30")
                consoleout(tl.CalcJ60All(n, bTest), n, "60")
                consoleout(tl.CalcJ90All(n, bTest), n, "90")
                consoleout(tl.CalcJ120All(n, bTest), n, "120")
            Next
            'Next
        Catch ex As Exception
            Throw
        End Try
    End Sub
    Private Enum Mode
        all
        allLimited
        valls1
        valls2
        fang1
        fang3
        debels
        clones
        phase1
        phase2
        valls3
        peaks
        diversity
        valls3a
        valls3b
        valls3c
        j301k
        j3050k
    End Enum
    Sub main()
        Try
            Console.ForegroundColor = ConsoleColor.Gray
            Dim tl As New clsTaskLib
            Debug.Print("-------------------------------------------------")
1:
            Console.WriteLine("Please choose the program mode")
            Console.WriteLine("")
            Console.WriteLine("[A] All tests")
            Console.WriteLine("[C] Clones (activity lists) allowed")
            Console.WriteLine("[D] Debels")
            Console.WriteLine("[F1] Fang/Wang Version 1 and 2")
            Console.WriteLine("[F3] Fang/Wang Version 3")
            Console.WriteLine("[P] Peaks restriction")
            Console.WriteLine("[P1] Phase 1 Extended")
            Console.WriteLine("[V1] Default settings - Standard set")
            Console.WriteLine("[V2] Default settings - J120 Ext")
            Console.WriteLine("")
            Dim bAll As Boolean = False
            bAllLimited = False
            Dim mode As Mode = mode.all
            Dim sin As String = Console.ReadLine()
            Select Case sin.ToUpper
                Case "A"
                    bAll = True
                Case "X"
                    mode = myconst.Mode.diversity
                Case "C"
                    mode = myconst.Mode.clones
                Case "D"
                    mode = myconst.Mode.debels
                Case "F1"
                    mode = myconst.Mode.fang1
                Case "F3"
                    mode = myconst.Mode.fang3
                Case "P"
                    mode = myconst.Mode.peaks
                Case "P1A"
                    mode = myconst.Mode.phase1
                Case "P1"
                    mode = myconst.Mode.phase2
                Case "V1"
                    mode = myconst.Mode.valls1
                Case "V2"
                    mode = myconst.Mode.valls2
                Case "V3"
                    mode = myconst.Mode.valls3
                Case "V3A"
                    mode = myconst.Mode.valls3a
                Case "V3B"
                    mode = myconst.Mode.valls3b
                Case "V3C"
                    mode = myconst.Mode.valls3c
                Case "B"
                    mode = myconst.Mode.allLimited
                    bAll = True
                    bAllLimited = True
                Case "J301K"
                    mode = myconst.Mode.j301k
                Case "J3050K"
                    mode = myconst.Mode.j3050k
                Case Else

                    Console.ForegroundColor = ConsoleColor.Red
                    Console.WriteLine("Mode unknown!")
                    Console.ForegroundColor = ConsoleColor.Gray
                    GoTo 1
            End Select

            Console.WriteLine("++++++++++++++++++++++++++++")
            Console.WriteLine("++++ Mode " & sin & " begin  ++++++++")
            Console.WriteLine("++++++++++++++++++++++++++++")
            Console.WriteLine("")

            If mode = myconst.Mode.j301k Then
                Config_Valls_Default()
                TestSet_30_1000()
            End If
            If mode = myconst.Mode.j3050k Then
                Config_Valls_Default()
                TestSet_30_50000()
            End If
            If mode = myconst.Mode.diversity Then
                Config_Valls_Default()
                TestSet_diversity()
            End If
            If bAll Or mode = myconst.Mode.clones Then
                Config_Valls_Default()
                TestSet_allow_Clones()
            End If
            If bAll Or mode = myconst.Mode.fang3 Then
                Config_Valls_Default()
                TestSet_fangWangv3()
            End If
            If bAll Or mode = myconst.Mode.fang1 Then
                Config_Valls_Default()
                TestSet_fangWang()
            End If
            If bAll Or mode = myconst.Mode.debels Then
                Config_Valls_Default()
                TestSet_debels()
            End If
            If bAll Or mode = myconst.Mode.phase2 Then
                Config_Valls_Default()
                TestSet_phase1_ext()
            End If
            If mode = myconst.Mode.phase1 Then
                Config_Valls_Default()
                TestSet_phase1()
            End If
            If bAll Or mode = myconst.Mode.peaks Then
                Config_Valls_Default()
                TestSet_Peaks()
            End If

            If bAll Or mode = myconst.Mode.valls1 Then
                Config_Valls_Default()
                'standard sets
                Console.WriteLine("--------- HGA Default Standard set -------")
                Dim nSch() As Int32 = New Int32() {1000, 5000, 50000}
                If mode = myconst.Mode.allLimited Then
                    nSch = New Int32() {1000, 5000}
                End If
                For Each n As Int32 In nSch
                    If n = 50000 Then
                        detectClones = False
                    End If
                    consoleout(tl.CalcJ30All(n), n, "30")
                    Config_Valls_Default()
                    consoleout(tl.CalcJ60All(n), n, "60")
                    consoleout(tl.CalcJ90All(n), n, "90")
                    consoleout(tl.CalcJ120All(n), n, "120")
                Next
            End If
            If bAll Or mode = myconst.Mode.valls2 Then
                Config_Valls_Default()
                'J120 ext set
                Console.WriteLine("--------- HGA Default 120 EXT -------")
                Dim nSch() As Int32 = New Int32() {2500, 10000, 25000, 100000}
                If mode = myconst.Mode.allLimited Then
                    nSch = New Int32() {2500, 10000, 25000}
                End If
                For Each n As Int32 In nSch
                    consoleout(tl.CalcJ120All(n), n, "120")
                Next
            End If
            If mode = myconst.Mode.valls3 Then
                Config_Valls_Default()
                detectClones = False
                divider = 2
                Console.WriteLine("--------- HGA Default 120 EXT Special 1-------")
                Dim nSch() As Int32 = New Int32() {1000, 100000}
                For Each n As Int32 In nSch
                    consoleout(tl.CalcJ120All(n), n, "120")
                Next
            End If
            If mode = myconst.Mode.valls3a Then
                Config_Valls_Default()
                Console.WriteLine("--------- HGA Default 120 EXT Special 2-------")
                Dim nSch() As Int32 = New Int32() {100000}
                For Each n As Int32 In nSch
                    consoleout(tl.CalcJ120All(n, False, 0), n, "120")
                Next
            End If
            If mode = myconst.Mode.valls3b Then
                Config_Valls_Default()
                Console.WriteLine("--------- HGA Default 120 EXT Special 3-------")
                Dim nSch() As Int32 = New Int32() {100000}
                For Each n As Int32 In nSch
                    consoleout(tl.CalcJ120All(n, , 199), n, "120")
                Next
            End If
            If mode = myconst.Mode.valls3c Then
                Config_Valls_Default()
                Console.WriteLine("--------- HGA Default 120 EXT Special 4-------")
                Dim nSch() As Int32 = New Int32() {100000}
                For Each n As Int32 In nSch
                    consoleout(tl.CalcJ120All(n, , 399), n, "120")
                Next
            End If
            Console.WriteLine("+++++++++ Finished +++++++")
            Console.ReadKey()
            Exit Sub
        Catch ex As Exception
            Console.ForegroundColor = ConsoleColor.Red
            Console.WriteLine(ex.ToString)
            Console.ForegroundColor = ConsoleColor.Gray
            Console.ReadKey()
        End Try
    End Sub
    Private Function Compare1(ByVal a As KeyValuePair(Of Int32, Int32), ByVal b As KeyValuePair(Of Int32, Int32)) As Int32
        Try
            Return a.Key.CompareTo(b.Key)
        Catch ex As Exception
            Throw
        End Try
    End Function
    Public Function GetAL(ByRef proj As clsProject) As HashSet(Of Int32)
        Try
            'Dim sd As New SortedDictionary(Of Single, Int32)
            Dim order As New List(Of KeyValuePair(Of Int32, Int32))
            Dim i As Int32 = 0
            Dim result = From x In proj.TasksA Order By x.PlanedAt Ascending, x.Key Ascending
            Dim al As New HashSet(Of Int32)
            Dim a As Int32 = 0
            Dim prePos As Int32 = 0
            For Each o In result
                If a > 0 Then
                    al.Add(o.Key)
                    proj.TasksA(o.Key).Position = a
                    If diversityControl Then
                        proj.TasksA(o.Key).DistanceInALToPre = o.PlanedAt - prePos
                        prePos = o.PlanedAt
                    End If
                End If
                a += 1
            Next
            If diversityControl Then
                Dim resultDistance = (From x In proj.TasksA Order By x.DistanceInALToPre Descending
                                     Select x.DistanceInALToPre).Take(CInt(0.5 * proj.TasksA.Count))

                Dim s = resultDistance.Sum()
                proj.MaxDistance = s
                ' proj.Fitness = proj.Fitness
            End If
            Return al
        Catch ex As Exception
            Throw
        End Try
    End Function

    <Extension()> _
    Public Function SubArray(Of T)(ByVal values(,) As T, ByVal _
    row_min As Int32, ByVal row_max As Int32, ByVal _
    col_min As Int32, ByVal col_max As Int32) As T(,)
        Dim num_rows As Int32 = row_max - row_min + 1
        Dim num_cols As Int32 = col_max - col_min + 1
        Dim result(0 To num_rows - 1, 0 To num_cols - 1) As T

        For row As Int32 = 0 To num_rows - 1
            For col As Int32 = 0 To num_cols - 1
                result(row, col) = values(row + row_min, col + _
                    col_min)
            Next col
        Next row

        Return result
    End Function
    <Extension()> _
    Public Function SubArrayB(Of T)(ByVal values()() As T, ByVal _
    row_min As Int32, ByVal row_max As Int32, ByVal _
    col_min As Int32, ByVal col_max As Int32) As T(,)
        Dim num_rows As Int32 = row_max - row_min + 1
        Dim num_cols As Int32 = col_max - col_min + 1
        Dim result(0 To num_rows - 1, 0 To num_cols - 1) As T

        For row As Int32 = 0 To num_rows - 1
            Array.Copy(values, col_min, result, 0, col_max)
            'For col As Int32 = 0 To num_cols - 1
            '    result(row, col) = values(row + row_min, col + _
            '        col_min)
            'Next col
        Next row

        Return result
    End Function

    Public Function ListToString(ByVal xlist As HashSet(Of Int32)) As String

        Try
            Dim result As New StringBuilder()
            For Each itm As Int32 In xlist
                result.Append(itm.ToString)
                result.Append("|")
            Next

            Return result.ToString
        Catch ex As Exception
            Throw
        End Try

    End Function
    Public Function ListToStringB(ByVal xlist As HashSet(Of Int32)) As StringBuilder

        Try
            Dim result As New StringBuilder()
            For Each itm As Int32 In xlist
                result.Append(itm.ToString)
                result.Append("|")
            Next
            Return result
        Catch ex As Exception
            Throw
        End Try

    End Function
    Public Function ListToInt32(ByVal xlist As HashSet(Of Int32)) As Int32

        Try
            Dim result As Int32
            Dim x As Int32 = 1
            For Each itm As Int32 In xlist
                result += itm * x
                x += 1
            Next
            Return result
        Catch ex As Exception
            Throw
        End Try

    End Function
    Public Function PostToString(ByVal projInfo As clsProject) As String
        Try
            Dim result As New StringBuilder()
            For Each itm As clsTask In projInfo.TasksA
                result.Append("{")
                result.Append(HashToString(itm.Post, ", "))
                result.Append("}")
                If Not itm Is projInfo.TasksA.Last Then
                    result.Append(", ")
                End If

            Next
            Return result.ToString
        Catch ex As Exception
            Throw
        End Try
    End Function
    Public Function ResToString(ByVal projInfo As clsProject) As String
        Try
            Dim result As New StringBuilder()
            For Each res As String In projInfo.RenewableResources.Keys
                result.Append("|")
                For Each itm As clsTask In projInfo.TasksA
                    result.Append(itm.RenewableResources(res).ToString)
                    If Not itm Is projInfo.TasksA.Last Then
                        result.Append(", ")
                    End If
                Next
            Next
            result.Append("|")
            Return result.ToString
        Catch ex As Exception
            Throw
        End Try
    End Function

    Public Function PlanedToString(ByVal projInfo As clsProject) As StringBuilder

        Try
            Dim result As New StringBuilder()
            Dim i As Int32 = 0
            For Each itm As clsTask In projInfo.TasksA
                If i > 0 Then
                    result.Append(itm.PlanedAt.ToString)
                    If Not itm Is projInfo.TasksA.Last Then
                        result.Append(", ")
                    End If
                End If
                i += 1
            Next
            Return result
        Catch ex As Exception
            Throw
        End Try

    End Function
    Public Function TaskDurToString(ByVal projInfo As clsProject) As String

        Try
            Dim result As New StringBuilder()
            Dim i As Int32 = 0
            For Each itm As clsTask In projInfo.TasksA
                If i > 0 Then
                    result.Append(itm.Duration.ToString)
                    If Not itm Is projInfo.TasksA.Last Then
                        result.Append(", ")
                    End If
                End If
                i += 1
            Next
            Return result.ToString
        Catch ex As Exception
            Throw
        End Try

    End Function
    Public Function HashToString(ByVal xlist As HashSet(Of Int32), Optional delimiter As String = "|") As String
        Try
            Dim result As New StringBuilder()
            Dim count As Int32 = xlist.Count - 1
            Dim x As Int32 = 0
            For Each itm As Int32 In xlist
                result.Append(itm.ToString)
                If x < count Then
                    result.Append(delimiter)
                End If
                x += 1
            Next

            Return result.ToString
        Catch ex As Exception
            Throw
        End Try
    End Function
    Public Function DicToString(ByVal xlist As Dictionary(Of String, Int32), Optional delimiter As String = "|") As String
        Try
            Dim result As New StringBuilder()
            Dim count As Int32 = xlist.Values.Count - 1
            Dim x As Int32 = 0
            For Each itm As Int32 In xlist.Values
                result.Append(itm.ToString)
                If x < count Then
                    result.Append(delimiter)
                End If
                x += 1
            Next

            Return result.ToString
        Catch ex As Exception
            Throw
        End Try
    End Function
    Public Function CloneDictionary(Of TKey, TValue As ICloneable)(original As Dictionary(Of TKey, TValue)) As Dictionary(Of TKey, TValue)
        Try
            Dim ret As New Dictionary(Of TKey, TValue)(original.Count, original.Comparer)
            For Each entry As KeyValuePair(Of TKey, TValue) In original
                ret.Add(entry.Key, entry.Value.Clone())
            Next
            Return ret
        Catch ex As Exception
            Throw
        End Try
    End Function

    Public Function CloneHashSet(Of TKey)(original As HashSet(Of TKey)) As HashSet(Of TKey)
        Try
            Dim ret As New HashSet(Of TKey)
            For Each entry In original
                ret.Add(entry)
            Next
            Return ret
        Catch ex As Exception
            Throw
        End Try
    End Function

    Public Function SuccessorValidation(ByVal pruef As clsProject) As Boolean
        Try
            Dim valid As Boolean = True
            For Each task As clsTask In pruef.TasksA
                If task.PlanedAt < 0 Then
                    Throw New Exception("invalid schedule: Task " & task.Key & " planed negative")
                End If
                For Each post As Int32 In task.Post
                    If post = 0 Then
                        'last node
                        Exit For
                    End If
                    If pruef.TasksA(post).PlanedAt < task.PlanedAt + task.Duration Then
                        valid = False
                        Throw New Exception("invalid schedule: Task " & task.Key & " Post " & post)
                    End If
                Next
            Next
            Return valid
        Catch ex As Exception
            Throw
        End Try

    End Function
    Public Function ResourceValidation(ByVal pruef As clsProject) As Boolean
        Try
            Dim resValid As Boolean = True
            Dim t As Int32 = 0
            For t = 0 To pruef.Fitness

                For Each res As String In pruef.RenewableResources.Keys
                    Dim resBelegt As Int32 = 0
                    For Each task As clsTask In pruef.TasksA
                        If task.PlanedAt <= t And t <= task.PlanedAt + task.Duration - 1 Then
                            'task active
                            resBelegt += task.RenewableResources(res)
                        End If
                    Next
                    If resBelegt > pruef.RenewableResources(res) Then
                        resValid = False
                        Throw New Exception("invalid schedule: RES " & res & " t " & t)
                        Exit For
                    End If
                Next
            Next
            Return resValid
        Catch ex As Exception
            Throw
        End Try
    End Function

    Public Function DeepClone(obj As Object) As Object
        Dim objResult As Object = Nothing
        Using ms As New MemoryStream()
            Dim bf As New BinaryFormatter()
            bf.Serialize(ms, obj)
            ms.Position = 0
            objResult = bf.Deserialize(ms)
        End Using
        Return objResult
    End Function
    Public Function UpdateCloneList(ByRef clonelist As HashSet(Of Int32), al As HashSet(Of Int32)) As Boolean
        Try
            ' Dim entry As String = ListToStringB(al).ToString
            ' Dim co As New myComparer
            'Dim y = ab.Contains(b, co)
            'Dim z = ab.Contains(c, co)
            Dim entry As Int32 = ListToInt32(al)
            If clonelist.Contains(entry) Then
                clonelist.Remove(entry)
            End If
        Catch ex As Exception
            Throw
        End Try
    End Function

    Public Function IsClone(ByRef clonelist As HashSet(Of Int32), al As HashSet(Of Int32)) As Boolean
        Try
            ''Dim entry As String = ListToStringB(al).ToString
            'Dim co As New myComparer
            Dim entry As Int32 = ListToInt32(al)
            If clonelist.Contains(entry) Then

                '  Debug.Write("Clones " & clonelist.Count)
                Return False
            Else
                clonelist.Add(entry)
                Return True
            End If
        Catch ex As Exception
            Throw
        End Try
    End Function
End Module
